#ifndef _LIGHT_H_
#define _LIGHT_H_

#include "Color.h"
#include "SharpShooterMath.h"

//! sharpShooter
namespace sharpShooter
{
	//! Scene
	namespace Scene
	{

		///@brief enumeration for different type of lights.
		enum LIGHT_TYPE
		{

			POINT_T = 0,

			DIRECTIONAL,

			SPOT,
		};

		///@class CLight 
		///@brief Base class of different kinds of lights. It's contents is just about the color of the light.
		class _SharpShooterExport CLight
		{
		public:
			///@brief Constructor
			///@param color color of the light.	
			inline CLight(Core::CColorRGBAf color)
				:m_Color(color),m_IsOn(false)
			{	}
			inline CLight():m_Color(Core::CColorRGBAf(1.0f,1.0f,1.0f,1.0f)),m_IsOn(false)
			{	}

			///@brief Set the color of the light.
			///@param color Color of the light.
			inline void setColor(Core::CColorRGBAf color)
			{
				m_Color = color;	}

			///@brief Get the color of the light.
			///@return light color.
			inline Core::CColorRGBAf getColor(void)const
			{
				return m_Color;
			}
			inline bool getIsOn(void)const
			{
				return m_IsOn;
			}
			inline void turnOn(void)
			{
				m_IsOn = true;
			}
			inline void turnOff(void)
			{
				m_IsOn = false;
			}
		protected:
			Core::CColorRGBAf m_Color;	
			bool m_IsOn;
		};

		///@brief point light,It has a position in space and a radiate where the light can work.
		class _SharpShooterExport CPointLight: public CLight
		{
		public:
			inline CPointLight(Core::CColorRGBAf color, Core::Vector3f position	,float radius,float attenuation)
				:CLight(color),m_Position(position),m_Radius(radius),m_Attenuation(attenuation){}
			inline CPointLight()
			{
				m_Position = Core::Vector3f(0.0f,0.0f,0.0f);
				m_Radius = 100.0f;
				m_Attenuation = 0.01f;
			}

			inline void setPosition(Core::Vector3f position)
			{
				m_Position = position;
			}
			inline Core::Vector3f getPosition(void)const
			{
				return m_Position;
			}
			inline void setRadius(float radius)
			{
				m_Radius = radius;
			}
			inline float getRadius(void)
			{
				return m_Radius;
			}
			inline void setAttenuation(float attenuation)
			{
				m_Attenuation = attenuation;
			}
			inline float getAttenuation(void)
			{
				return m_Attenuation;
			}
		private:
			Core::Vector3f m_Position;
			float m_Radius;
			float m_Attenuation;
		};

		///@class CDirectionalLight
		///@brief directional light, coming from a direction from a infinite distance without attenuation.
		class _SharpShooterExport CDirectionalLight: public CLight
		{
		public:
			inline CDirectionalLight(Core::CColorRGBAf color	,Core::Vector3f direction=Core::Vector3f(0.0f,1.0f,0.0f))
				:CLight(color),m_Direction(direction){}
			inline CDirectionalLight():m_Direction(Core::Vector3f(0.0f,1.0f,0.0f))
			{

			}

			inline void setDirection(Core::Vector3f direction)
			{
				m_Direction = direction;
			}
			inline Core::Vector3f getDirection(void)
			{
				return m_Direction;
			}
		private:
			Core::Vector3f m_Direction;

		};

		///@brief spot light, It has a position in space , a direction and a limited cone of influence.
		class _SharpShooterExport CSpotLight: public CLight
		{
		public:
			inline CSpotLight(Core::CColorRGBAf color,Core::Vector3f position, Core::Vector3f direction, float coneAngle,float fallout):
			CLight(color),m_Position(position),m_Direction(direction),m_Fallout(fallout),m_ConeAngle(coneAngle)
			{
			}
			inline CSpotLight():m_Position(Core::Vector3f(0.0f,0.0f,0.0f)),m_Direction(0.0f,1.0f,0.0f)
				,m_Fallout(0.0f),m_ConeAngle(Core::MathLib::PI/6)
			{

			}
			inline void setPosition(Core::Vector3f position)
			{
				m_Position = position;
			}
			inline Core::Vector3f getPosition(void)
			{
				return m_Position;
			}

			inline void setDirection(Core::Vector3f direction)
			{
				m_Direction = direction;
			}
			inline Core::Vector3f getDirection(void)
			{
				return m_Direction;
			}

			inline void setConeAngle(float Cone)
			{
				m_ConeAngle = Cone;
			}
			inline float getConeAngle(void)
			{
				return m_ConeAngle;
			}

			inline void setFallout(float fallout)
			{
				m_Fallout = fallout;
			}
			inline float getFallout(void)
			{
				return m_Fallout;
			}

		private:
			Core::Vector3f m_Position;
			Core::Vector3f m_Direction;
			float m_ConeAngle;
			float m_Fallout;
		};

	}
}

#endif